VISUALIZAÇÃO DE DADOS COM O GGPLOT2

Autor

João Ricardo F. de Lima

Data de Publicação

8 de março de 2024


Visualização de Dados com o ggplot2 1

O ggplot2 é um pacote do R para a produção de gráficos. A ideia de que você pode construir cada gráfico a partir dos mesmos componentes: um conjunto de dados, um sistema de coordenadas e geoms – marcas visuais que representam pontos de dados.

Quais as principais vantagens do ggplot2?

  • Gramática de gráficos consistente;
  • Especificação de plotagem em um alto nível de abstração;
  • Muito flexível;
  • Sistema de temas para polir a aparência do gráfico;
  • Sistema gráfico completo e maduro.

Contudo, ele pode parecer meio “assustador” quando se tem o primeiro contato.

A Idéia básica é especificar separadamente blocos de construção de plotagem e combiná-los para criar qualquer tipo de exibição gráfica que você deseja.

Os blocos de construção de um gráfico incluem:

  • Dados;
  • Mapeamento estético;
  • Objeto geométrico;
  • Transformações estatísticas;
  • Escalas;
  • Ajustes de posição;
  • Facetas, entre outros.

A instalação pode ser feita de diversas maneiras:

# The easiest way to get ggplot2 is to install the whole tidyverse:
install.packages("tidyverse")

# Alternatively, install just ggplot2:
install.packages("ggplot2")

# Or the development version from GitHub:
# install.packages("pak")
pak::pak("tidyverse/ggplot2")

Para exibir valores, mapeie variáveis nos dados para propriedades visuais do geom (estética), como tamanho, cor e localizações x e y. Preencha o modelo abaixo para construir um gráfico.

ggplot(data = <Data>) +
  <Geom_Function>(mapping = aes(<Mappings>),
  stat = <Stat>,
  position = <Position>) +
  <Coordinate_Function> +
  <Facet_Function> +
  <Scale_Function> +
  <Theme_Function>

Dados, uma função Geom e mapeamentos Aes são necessários. As funções Estatística, Posição e Coordenada, Faceta, Escala e Tema não são necessárias se pode usar o default.

  • ggplot(data = mpg, aes(x = cty, y = hwy)): inicia um gráfico ao qual você finaliza adicionando camadas. Adicione uma função geom por camada.

  • last_plot(): Mostra o último gráfico.

  • ggsave(“plot.png”, width = 5, height = 5): Salva o último gráfico como um arquivo 5’ x 5’ chamado “plot.png” no diretório de trabalho. Corresponde o tipo de arquivo à extensão do arquivo.

AES

Values de AES mais comuns são:

  • color and fill: String (“red”, “#RRGGBB”), sendo este último em número hexadecimal. 2

  • linetype: Integer or string (0 = “blank”, 1 = “solid”, 2 = “dashed”, 3 = “dotted”, 4 = “dotdash”, 5 = “longdash”, 6 = “twodash”).

  • size: Integer (line width in mm for outlines).

  • linewidth: Integer (line width in mm for lines).

  • shape: Integer/shape name or a single character (“a”).

    • shape integer/name pairs: 0 = “square open”, 1 = “circle open”, 2 = “triangle open”, 3 = “plus”, 4 = “cross”, 5 = “diamond open”, 6 = “triangle down open”, 7 = “square cross”, 8 = “asterisk”, 9 = “diamond plus”, 10 = “circle plus”, 11 = “star”, 12 = “square plus”, 13 = “circle cross”, 14 = “square triangle”, 15 = “square”, 16 = “circle”, 17 = “triangle”, 18 = “diamond”, 19 = “circle small”, 20 = “bullet”, 21 = “circle filled”, 22 = “square filled”, 23 = “diamond filled”, 24 = “triangle filled”, 25 = “triangle down filled”

Geoms

Use uma função geom para representar pontos de dados, use as propriedades estéticas do geom para representar variáveis. Cada função retorna uma camada.

Exemplos

Gráfico de Colunas ou Barras

library(sidrar)
library(dplyr)

# Volume produzido com Manga no Nordeste em toneladas
raw_volume_manga_ne <- sidrar::get_sidra(api = "/t/5457/n2/2/v/214/p/last%2020/c782/40262")

str(raw_volume_manga_ne)
'data.frame':   20 obs. of  13 variables:
 $ Nível Territorial (Código)                             : chr  "2" "2" "2" "2" ...
 $ Nível Territorial                                      : chr  "Grande Região" "Grande Região" "Grande Região" "Grande Região" ...
 $ Unidade de Medida (Código)                             : chr  "1017" "1017" "1017" "1017" ...
 $ Unidade de Medida                                      : chr  "Toneladas" "Toneladas" "Toneladas" "Toneladas" ...
 $ Valor                                                  : num  614215 610177 702925 953217 970786 ...
 $ Grande Região (Código)                                 : chr  "2" "2" "2" "2" ...
 $ Grande Região                                          : chr  "Nordeste" "Nordeste" "Nordeste" "Nordeste" ...
 $ Variável (Código)                                      : chr  "214" "214" "214" "214" ...
 $ Variável                                               : chr  "Quantidade produzida" "Quantidade produzida" "Quantidade produzida" "Quantidade produzida" ...
 $ Ano (Código)                                           : chr  "2003" "2004" "2005" "2006" ...
 $ Ano                                                    : chr  "2003" "2004" "2005" "2006" ...
 $ Produto das lavouras temporárias e permanentes (Código): chr  "40262" "40262" "40262" "40262" ...
 $ Produto das lavouras temporárias e permanentes         : chr  "Manga" "Manga" "Manga" "Manga" ...
# Volume produzido com Manga no Nordeste em toneladas
volume_manga_ne <- raw_volume_manga_ne |> 
  dplyr::select(
    "date"     = `Ano`,
    "variable" = `Variável`,
    "value"    = `Valor`
  ) |> 
  dplyr::as_tibble()

volume_manga_ne <- volume_manga_ne |> 
  dplyr::mutate(
    value = value / 1000 # converter em mil toneladas
  )

# Gráfico com o ggplot2
library(ggplot2)

g1 <- ggplot() +
  geom_col(data=volume_manga_ne, aes(x=date, y=value))

g1

g2 <- ggplot(data=volume_manga_ne, aes(x=date, y=value)) +
  geom_bar(stat="identity")

g2

É possível, então, melhorar a qualidade dos gráficos, fazendo alterações diversas

g3 <- ggplot() +
  geom_col(data=volume_manga_ne, aes(x=date, y=value, fill="variable"))+
  scale_fill_manual(values="gold") +#muda a cor da barra
  labs(y= "Mil Toneladas", x= "Anos", title='Evolução do volume produzido de manga no Nordeste: 2003 a 2022.',
       caption = "Fonte: IBGE, 2024.")
g3

g4 <- ggplot() +
  geom_col(data=volume_manga_ne, aes(x=date, y=value, fill="variable"))+
  scale_fill_manual(values="gold") +#muda a cor da barra
  labs(y= "Mil Toneladas", x= "Anos", title='Evolução do volume produzido de manga no Nordeste: 2003 a 2022.',
       caption = "Fonte: IBGE, 2024.")+
  scale_y_continuous(n.breaks = 10)+
  theme_minimal() + #Definindo tema
   theme(legend.position = "bottom", legend.title = element_blank(),
        legend.text=element_text(size=12)) # Definindo posição da legenda
g4

g5 <- ggplot() +
  geom_col(data=volume_manga_ne, aes(x=date, y=value, fill="variable"))+
  scale_fill_manual(values="gold") +#muda a cor da barra
  labs(y= "Mil Toneladas", x= "Anos", title='Evolução do volume produzido de manga no Nordeste: 2003 a 2022.',
       caption = "Fonte: IBGE, 2024.")+
  scale_y_continuous(n.breaks = 10)+
  theme_minimal() + #Definindo tema
   theme(axis.text.x = element_text(margin = margin(b=10)), #mais espaço entre valores do eixo e nome do eixo
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(), # retirando as linhas
        plot.title = element_text(hjust = 0.5, size=14, face="italic"), #ajuste titulo
        plot.caption = element_text(hjust = 0, size=10), #ajuste Fonte
        legend.position = "none") # Definindo posição da legenda
 # Nome do eixo mais para baixo
g5

Gráfico de Colunas com duas variáveis

library(sidrar)
library(dplyr)
library(tidyverse)

# Volume produzido com Manga no Nordeste em toneladas
raw_volume_manga <- sidrar::get_sidra(api = "/t/5457/n2/2/n8/2602,2902/v/214/p/last%2020/c782/40262")

str(raw_volume_manga)
'data.frame':   60 obs. of  13 variables:
 $ Nível Territorial (Código)                             : chr  "2" "2" "2" "2" ...
 $ Nível Territorial                                      : chr  "Grande Região" "Grande Região" "Grande Região" "Grande Região" ...
 $ Unidade de Medida (Código)                             : chr  "1017" "1017" "1017" "1017" ...
 $ Unidade de Medida                                      : chr  "Toneladas" "Toneladas" "Toneladas" "Toneladas" ...
 $ Valor                                                  : num  614215 610177 702925 953217 970786 ...
 $ Grande Região e Mesorregião Geográfica (Código)        : chr  "2" "2" "2" "2" ...
 $ Grande Região e Mesorregião Geográfica                 : chr  "Nordeste" "Nordeste" "Nordeste" "Nordeste" ...
 $ Variável (Código)                                      : chr  "214" "214" "214" "214" ...
 $ Variável                                               : chr  "Quantidade produzida" "Quantidade produzida" "Quantidade produzida" "Quantidade produzida" ...
 $ Ano (Código)                                           : chr  "2003" "2004" "2005" "2006" ...
 $ Ano                                                    : chr  "2003" "2004" "2005" "2006" ...
 $ Produto das lavouras temporárias e permanentes (Código): chr  "40262" "40262" "40262" "40262" ...
 $ Produto das lavouras temporárias e permanentes         : chr  "Manga" "Manga" "Manga" "Manga" ...
# Volume produzido com Manga no Nordeste em toneladas
volume_manga <- raw_volume_manga |> 
  dplyr::select(
    "date"     = `Ano`,
    "value"    = `Valor`,
    "regiao"   = `Grande Região e Mesorregião Geográfica`
  ) |> 
  dplyr::mutate(
    value = value / 1000) |> # converter em mil toneladas
  dplyr::as_tibble()

volume_manga <- tidyr::pivot_wider(
  data = volume_manga,
  id_cols = date,
  names_from = regiao,
  values_from = value
)

volume_manga <- volume_manga |> 
  dplyr::mutate(
    Vale = `São Francisco Pernambucano (PE)` + `Vale São-Franciscano da Bahia (BA)`) |>
  dplyr::select(date, Nordeste, Vale)

# Gráfico com duas colunas
g6 <- ggplot() +
  geom_col(data=volume_manga, aes(x=date, y=Nordeste, fill="variable"))+
  scale_fill_manual(values="gold") +#muda a cor da barra
  labs(y= "Mil Toneladas", x= "Anos", title='Evolução do volume produzido de manga no Nordeste: 2003 a 2022.',
       caption = "Fonte: IBGE, 2024.")+
  scale_y_continuous(n.breaks = 10)+
  theme_minimal() + #Definindo tema
   theme(axis.text.x = element_text(margin = margin(b=10)), #mais espaço entre valores do eixo e nome do eixo
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(), # retirando as linhas
        plot.title = element_text(hjust = 0.5, size=14, face="italic"), #ajuste titulo
        plot.caption = element_text(hjust = 0, size=10), #ajuste Fonte
        legend.position = "none") # Definindo posição da legenda
 # Nome do eixo mais para baixo
g6

g7 <- ggplot(data=volume_manga, aes(x=date)) +
  geom_col(aes(y=Vale, fill="variable"))+
  geom_col(aes(y=Nordeste, fill="variable"))+
  labs(y= "Mil Toneladas", x= "Anos", title='Evolução do volume produzido de manga no Nordeste e Vale do São Francisco: 2003 a 2022.',
       caption = "Fonte: IBGE, 2024.")+
  scale_y_continuous(n.breaks = 10)+
  theme_minimal() + #Definindo tema
   theme(axis.text.x = element_text(margin = margin(b=10)), #mais espaço entre valores do eixo e nome do eixo
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(), # retirando as linhas
        plot.title = element_text(hjust = 0.5, size=12, face="italic"), #ajuste titulo
        plot.caption = element_text(hjust = 0, size=10), #ajuste Fonte
        legend.position = "bottom") # Definindo posição da legenda
 # Nome do eixo mais para baixo
g7

library(reshape2)
volume_manga <- melt(volume_manga, id.var='date')

#Outra possibilidade

# Reorganizar novamente os dados para o formato long
#volume_manga_teste <- tidyr::pivot_longer(
#  data = volume_manga,
#  cols = Nordeste:Vale,
#  names_to = "regiao",
#  values_to = "value"
#)
#volume_manga_teste2 <- volume_manga_teste[order(volume_manga_teste $regiao),]

mycolors <- c("lightblue3", "gold")
g8 <- ggplot() +
  geom_col(data=volume_manga, aes(x=date, y=value, fill=variable), size=2, width = 0.7, 
           position = "dodge")+
  scale_fill_manual(values=mycolors)+
  labs(y= "Mil Toneladas", x= "Anos", title='Evolução do volume produzido de manga no Nordeste e Vale do São Francisco: 2003 a 2022.',
       caption = "Fonte: IBGE, 2024.")+
  theme_minimal() + #Definindo tema
  theme(axis.text.x = element_text(margin = margin(b=10)), #mais espaço entre valores do eixo e nome do eixo
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(), # retirando as linhas
        plot.title = element_text(hjust = 0.5, size=12, face="italic"), #ajuste titulo
        plot.caption = element_text(hjust = 0, size=9), #ajuste Fonte
        legend.title = element_blank(),
        legend.position = "bottom") # Definindo posição da legenda
# Nome do eixo mais para baixo
g8

Gráfico de Linhas

library(GetBCBData)
library(magrittr)

# Coleta e tratamento de dados
selic_ipca <- GetBCBData::gbcbd_get_series(
  id          = c("IPCA em 12 meses" = "13522", "Taxa SELIC" = "4189"),
  first.date  = "1999-08-01", 
  use.memoise = FALSE
) |> 
  dplyr::as_tibble() |> 
  dplyr::select(
    "date"     = ref.date, 
    "variable" = series.name, 
    value
  )

# Gráfico com apenas uma série
library(scales)

selic_ipca |>
  dplyr::filter(variable == "Taxa SELIC") |>
  ggplot2::ggplot(ggplot2::aes(x = date, y = value, colour = variable)) +
  ggplot2::geom_line(size = 1) +
  ggplot2::labs(title = "Taxa de Juros - Selic",
                x = "Anos",
                y = "% a.a.",
                caption = "Dados: SGS/BCB") +
  ggplot2::scale_colour_manual(values = "#282f6b") +
  scale_x_date(date_breaks = "2 years",
               labels = date_format("%Y"))+
  ggplot2::theme_minimal()+
  ggplot2::theme(legend.title = element_blank(),
                 legend.position = "bottom")

# Gráfico das duas séries

selic_ipca |>
  ggplot2::ggplot(ggplot2::aes(x = date, y = value, colour = variable)) +
  ggplot2::geom_line(size = 1) +
  ggplot2::labs(title = "Inflação e Taxa de Juros - Selic",
                x = "Anos",
                y = "% a.a.",
                caption = "Dados: SGS/BCB") +
  ggplot2::scale_colour_manual(values = c(
             "#282f6b", # azul
             "#b22200" # vermelho
  )) +
  ggplot2::theme_minimal()+
  ggplot2::theme(legend.title = element_blank(),
                 legend.position = "bottom")

# Gráfico das duas séries uma emabaixo da outra
selic_ipca %>% 
  ggplot2::ggplot(ggplot2::aes(x = date, y = value, colour = variable)) +
  ggplot2::geom_line(size = 1) +
  ggplot2::labs(title = "Inflação vs. Taxa de Juros - Selic",
                x = "",
                y = "% a.a.",
                caption = "Dados: SGS/BCB | Elaborado por: analisemacro.com.br") +
  ggplot2::scale_colour_manual(values = c(
             "#282f6b", # blue
             "#b22200" # red
  )) +
  ggplot2::facet_wrap(~variable, nrow = 2, scales = "free_y") +
  ggplot2::theme_minimal()+
  ggplot2::theme(legend.position = "none")

Gráfico de Linhas e Colunas

ipca <- selic_ipca |>
  dplyr::filter(variable == "IPCA em 12 meses")

selic <- selic_ipca |>
  dplyr::filter(variable == "Taxa SELIC")

  ggplot2::ggplot() +
  ggplot2::geom_col(data=ipca, aes(x=date, y=value, fill=variable))+
  ggplot2::geom_line(data=selic, aes(x = date, y = value, colour = variable), size = 1) +
  ggplot2::labs(title = "Inflação e Taxa de Juros - Selic",
                x = "Anos",
                y = "% a.a.",
                caption = "Dados: SGS/BCB") +
  ggplot2::scale_colour_manual(values =
             "#b22200" # vermelho
  ) +
    scale_fill_manual(values="#282f6b")+
    scale_x_date(date_breaks = "2 years",
               labels = date_format("%Y"))+
  ggplot2::theme_minimal()+
  ggplot2::theme(legend.title = element_blank(),
                 legend.position = "bottom")

Notas de rodapé

  1. Este material está baseado em (https://rstudio.github.io/cheatsheets/html/data-visualization.html) e no material do LES/UFF (https://bookdown.org/jarrais/ciencia-dados-r-modi/_book/construindo-graficos-com-o-ggplot2.html)↩︎

  2. No site (https://htmlcolorcodes.com/) é muito fácil encontrar os números hexadecimais para as cores.↩︎